package com.thanks.thinkchina.runner;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.thanks.thinkchina.config.ForeignExchangeRestClient;
import com.thanks.thinkchina.config.SnowflakeConfig;
import com.thanks.thinkchina.modules.entity.LiveRate;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
import org.springframework.transaction.support.TransactionTemplate;
import org.springframework.web.client.RestTemplate;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @ClassName : FixerApplicationRunner
 * @Description : 消费者加载类
 * @Author : yf.zhu
 * @Date: 2021-12-13 13:41
 */
@Slf4j
@Configuration
public class FixerApplicationRunner implements ApplicationRunner, Ordered {


    @Autowired
    private SnowflakeConfig snowflakeConfig;

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private ForeignExchangeRestClient foreignExchangeRestClient;

    @Autowired
    private TransactionTemplate transactionTemplate;

    /***
     * @author yf.zhu
     * @description SpringBoot启动后执行方法
     * @Param [args]
     * @date 2022/06/23 21:43
     * @return void  
     */
    @Override
    public void run(ApplicationArguments args) {
        log.info("启动后方法加载，{}", LocalDateTime.now());
        /***
         * 整体逻辑：
         *      每分钟轮训拉去一次 https://fixer.io/的汇率 如果有更新则直接更新数据库并更新汇率缓存 并睡眠30分钟
         *      数据库表分为三部分：
         *          第一部分是汇率枚举值表，第二部分是遍历汇率枚举值去获取相关汇率信息表
         *      如果考虑到高并发执行完入库之后可以直接更新缓存
         */
        for (;;){
            if (true){
                log.info("Start scheduled task ");
                LiveRate liveRate = foreignExchangeRestClient.liveRate();
                Map<String, BigDecimal> rates = liveRate.getRates();
                if (CollUtil.isNotEmpty(rates)){
                    // 走编程式事务处理
                    Boolean execute = this.transactionTemplate.execute((status) -> {
                        //TODO 首先清空汇率表历史数据

                        //TODO 将最新的汇率表数据入库处理 走雪花算法

                        //TODO 将最新的汇率数据入库到历史表

                        return Boolean.TRUE;
                    });
                    if (execute){
                        //TODO 更新缓存 保证数据库数据和缓存数据到一致性
                    }
                }
                ThreadUtil.sleep(30, TimeUnit.MINUTES);
                continue;
            }
        }

    }

    /***
     * @author yf.zhu
     * @description 此处只所以实现Ordered接口就是为了指定 SpringBoot启动后执行 方法的顺序
     * @Param []
     * @date 2022/06/23 21:43
     * @return int  
     */
    @Override
    public int getOrder() {
        return 1;
    }
}
